#include "HttpManger.h"
#include "DBManger.h"
#include "FishControl.h"
#include <FS.h>
#include <LittleFS.h>
#include "temperature/Temperature.h"

extern Temperature temper;

HttpManger::HttpManger(int port) : _httpServer(port), _httpUpdater(true) {}

HttpManger::~HttpManger() {}

void HttpManger::begin()
{
    _httpServer.on("/fishlamp", HTTP_GET, std::bind(&HttpManger::handleWeb, this, std::placeholders::_1));
    _httpServer.on("/fishlamp", HTTP_POST, std::bind(&HttpManger::handleWebSet, this, std::placeholders::_1));

    _httpServer.onNotFound(std::bind(&HttpManger::handleNotFound, this, std::placeholders::_1));
    _httpUpdater.setup(&_httpServer);
    _httpServer.begin();
    Serial.println(F("HTTP Control Center started"));
}

void HttpManger::handle()
{
    // _httpServer.handleClient();
}

void HttpManger::handleWeb(AsyncWebServerRequest *request)
{
    request->send(LittleFS, "/fishlamp.html", String());
}

void HttpManger::handleWebSet(AsyncWebServerRequest *request)
{
    if (request->headers() == 0)
    {
        request->send(404);
        return;
    }
    if (request->hasArg("op"))
    {
        int idx = request->arg("op").toInt();
        if (idx >= 0 && idx <= 3)
        {
            fishCtrl.setLamp(idx);
        }
        else
        {
            fishCtrl.setNextLamp();
        }
    }
    else if (request->hasArg("b"))
    {
        fishCtrl.setBrightness(request->arg("b").toInt());
    }
    else if (request->hasArg("sys") && request->arg("sys").equals("1"))
    {
        request->send(200, F("text/plain"), "{r:1}");
        delay(5000);
        ESP.reset();
        delay(2000);
    }
    else if (request->hasArg("tempture"))
    {
        DynamicJsonDocument doc(50);

        doc["t"] = temper.getTemp();
        String output;
        serializeJson(doc, output);

        request->send(200, F("text/plain"), output);
        return;
    }

    request->send(200, F("text/plain"), fishCtrl.getLampValue());
}

void HttpManger::handleNotFound(AsyncWebServerRequest *request)
{
    String path = request->url();
    if (LittleFS.exists(path) || LittleFS.exists(path + ".gz"))
    {
        request->send(LittleFS, path, String());
    }
    else
    {
        String message = "File Not Found\n\n";
        message += "URI: ";
        message += request->url();
        message += "\nMethod: ";
        message += (request->method() == HTTP_GET) ? "GET" : "POST";
        message += "\nArguments: ";
        message += request->args();
        message += "\n";

        for (uint8_t i = 0; i < request->args(); i++)
        {
            message += " " + request->argName(i) + ": " + request->arg(i) + "\n";
        }
        AsyncWebServerResponse *response = request->beginResponse(404, "text/plain", message);
        response->addHeader("Cache-Control", "no-cache, no-store, must-revalidate");
        response->addHeader("Pragma", "no-cache");
        response->addHeader("Expires", "-1");

        request->send(response);
    }
}

AsyncWebServer *HttpManger::webServer()
{
    return &_httpServer;
}

DNSServer *HttpManger::dns()
{
    return &_dns;
}